package com.veo.controller;

import com.veo.service.SyslogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.UUID;

@Component
@Aspect
public class SysLog {

    //开始时间
    private Date startTime;
    //类名
    private Class clazz;
    //方法
    private Method method;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private SyslogService syslogService;

    //前置通知获取访问的时间和方法的类和方法名
    @Before("execution(* com.veo.controller.*.*(..))")
    public void doBefore(JoinPoint jp) throws NoSuchMethodException {
        //获取访问的开始时间
        startTime=new Date();
        //获取访问的类
        clazz=jp.getTarget().getClass();
        //获取访问的方法名
        String methodName=jp.getSignature().getName();
        //获取方法的参数
        Object[] args = jp.getArgs();
        if (args==null||args.length==0){
            //获取无参的方法名
            method=clazz.getMethod(methodName);
        }else {
            // 有参数，就将args中所有元素遍历，获取对应的Class,装入到一个Class[]
            Class[] classArge=new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                classArge[i]=args[i].getClass();
            }
            //获取有参的方法名
            method=clazz.getMethod(methodName,classArge);
        }

    }


    //后置通知计算访问的时长和ip，URL路径，用户名
    @After("execution(* com.veo.controller.*.*(..))")
    public void doAfter(JoinPoint jp){
        long time=System.currentTimeMillis()-startTime.getTime();
        String url="";
        if (clazz!=null&&method!=null&&clazz!=SysLog.class){
            // 获取类上的@RequestMapping对象
            RequestMapping clazzAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
            if (clazzAnnotation!=null){
                String[] classValue=clazzAnnotation.value();
                // 获取方法上的@RequestMapping对象
                RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
                if (methodAnnotation!=null){
                    String[] methodValue = methodAnnotation.value();
                    url=classValue[0]+methodValue[0];
                    //获取ip
                    String ip=request.getRemoteAddr();
                    //通过spring-security获取当前用户
                    SecurityContext context = SecurityContextHolder.getContext();
                    User user = (User) context.getAuthentication().getPrincipal();
                    String username=user.getUsername();
                    //封装类对象
                    com.veo.domain.SysLog sysLog = new com.veo.domain.SysLog();
                    sysLog.setExecutionTime(time);
                    sysLog.setUsername(username);
                    sysLog.setIp(ip);
                    sysLog.setUrl(url);
                    sysLog.setMethod("[类名]"+clazz.getName()+"[方法名]"+method.getName());
                    sysLog.setVisitTime(startTime);
                    String id= UUID.randomUUID().toString().replace("-","").toUpperCase();
                    sysLog.setId(id);

                    syslogService.saveLog(sysLog);
                }
            }
        }

    }

}
